package com.taotao.sso.service.impl;

import java.util.List;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import com.taotao.common.TaotaoResult;
import com.taotao.jedis.JedisClient;
import com.taotao.mapper.TbUserMapper;
import com.taotao.pojo.TbUser;
import com.taotao.pojo.TbUserExample;
import com.taotao.pojo.TbUserExample.Criteria;
import com.taotao.sso.service.UserLoginService;
import com.taotao.utils.JsonUtils;
/**
 * 用户登录的接口实现类
 * @author created by wq
 * @date   Sep 6, 2017---8:28:46 AM
 * @return
 * @throws Exception<br/>
 *==========History========== <br/>
 * taotao-sso-service Sep 6, 2017
 */
@Service
public class UserLoginServiceImpl implements UserLoginService {

	//注入持久层
	@Autowired
	private TbUserMapper userMapper;
	
	@Autowired
	private JedisClient jedisClient;
	
	@Value("${TOKEN_PRE}")
	private String TOKEN_PRE;
	
	@Value("${REDIS_USERINFO_ALIVE}")
	private Integer REDIS_USERINFO_ALIVE;
	
	/**
	 * 1.2 用户登录功能：
	 */
	@Override
	public TaotaoResult userLogin(String username, String password) {
		//调用持久层
		TbUserExample example = new TbUserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<TbUser> list = userMapper.selectByExample(example);
		//判断list是否为空，排除掉用户名输错，在数据库中不匹配的情况。
		if(list == null || list.size() == 0){
			//在数据库中没有匹配到用户输入的username
			return TaotaoResult.build(400, "用户名输入错误");
		}
		//再从list中获得到第一个元素，其实也就只有一个
		TbUser user = list.get(0);
		//判断用户输入的密码是否 与 该用户在数据库中的密码一致，不一致，说明该用户在此次输入错误，给出提示
		if(!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())){
			return TaotaoResult.build(400, "密码输入错误，请重新输入");
		}
		//登录成功时生成token：前缀(在配置文件中读取)+uuid 
		String token = UUID.randomUUID().toString();
		
		//将用户的信息存入到redis【key：token value：json格式的用户信息】中，并设置过期时间
		jedisClient.set(TOKEN_PRE + ":" + token, JsonUtils.objectToJson(user));
		jedisClient.expire(TOKEN_PRE + ":" + token, REDIS_USERINFO_ALIVE);
		/**
		 * 返回结果：【注意：因为cookie和session都是一次会话{默认是当打开浏览器为一次新的会话开始，关闭浏览器时，此次会话结束}】
		 *        所以cookie一般是在web层的。  而在service层的是session。 此时要向将token加入到cookie中，
		 *        实现在各个浏览器间跨域请求，便需要在web层设置
		 *   jsonp: 跨域【域名不同，端口相同或域名相同，端口不同】传递，在到达域那接收不到送达域的json数据，而跨域是可以实现js的
		 *   		传递与接收， 所以我们可以自定义一个callback({json串}),然后将json转化为js。跨域时传递的是js文件，而在
		 *   		js到达目标域时，目标域再解析js文件，拿到对应的json串数据。便可实现用jsonp来跨域    
		 */
		//返回结果 
		return TaotaoResult.ok(token);
	}

	/**
	 * 1.3.通过token查询用户信息
	 */
	@Override
	public TaotaoResult getUserInfoByToken(String token) {
		/*
		 * 当查询订单时，会判断在redis中是否存在该用户的信息。先是从cookie中得到token，根据token的value(uuid)
		 * 	去redis中查找用户的信息。 在redis中用户的信息存的方式是： key为uuid  ,value为用户信息的json格式数据
		 */
		//先从cookie中取到token--->这是在web层做的事
		//1.根据token去redis中查询(在redis中的key为:TOKEN_PRE + ":" + token)
		String json = jedisClient.get(TOKEN_PRE + ":" + token);
		//2.判断redis中是否存在，若不存在直接返回去登录页面，存在则重置过期时间为最长
		if(StringUtils.isBlank(json)){
			//不存在用户信息，需要提示用户去登录
			return TaotaoResult.build(400, "该用户的登录时间到期，请去重新登录");
		}
		//重置过期时间
		jedisClient.expire(TOKEN_PRE + ":" + token, REDIS_USERINFO_ALIVE);
		//将json转换为pojo
		TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);
		//3.得到结果
		return TaotaoResult.ok(user);
	}
}
